<?php
// api/users.php
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    exit(0);
}

require_once 'db.php';

$method = $_SERVER['REQUEST_METHOD'];
$userID = $_GET['UserID'] ?? null; // Get ID from query parameter for GET(single), PUT, DELETE

switch($method) {
    case "GET":
        try {
            if ($userID !== null) {
                // Fetch single user (exclude password)
                $stmt = $pdo->prepare("SELECT UserID, Username, Role FROM User WHERE UserID = ?");
                $stmt->execute([$userID]);
                $user = $stmt->fetch();
                if ($user) {
                    echo json_encode($user);
                } else {
                    http_response_code(404);
                    echo json_encode(["error" => "User not found"]);
                }
            } else {
                // Fetch all users (exclude password)
                $stmt = $pdo->query("SELECT UserID, Username, Role FROM User ORDER BY UserID ASC");
                $users = $stmt->fetchAll();
                echo json_encode($users);
            }
        } catch (PDOException $e) {
            http_response_code(500);
            echo json_encode(["error" => "Failed to retrieve user data", "details" => $e->getMessage()]);
        }
        break;

    case "POST":
        $data = json_decode(file_get_contents("php://input"), true);

        if (!isset($data['Username'], $data['Password'], $data['Role']) || empty(trim($data['Username'])) || empty($data['Password']) || empty($data['Role'])) {
            http_response_code(400);
            echo json_encode(["error" => "Missing or empty required fields (Username, Password, Role)"]);
            exit;
        }
        if (!in_array($data['Role'], ['student', 'teacher', 'admin'])) {
             http_response_code(400);
             echo json_encode(["error" => "Invalid user role specified"]);
             exit;
        }

        $hashedPassword = password_hash($data['Password'], PASSWORD_DEFAULT);
        if ($hashedPassword === false) {
            http_response_code(500);
            echo json_encode(["error" => "Password hashing failed"]);
            exit;
        }

        try {
            // Check for duplicate username before inserting
            $stmtCheck = $pdo->prepare("SELECT UserID FROM User WHERE Username = ?");
            $stmtCheck->execute([$data['Username']]);
            if ($stmtCheck->fetch()) {
                http_response_code(409); // Conflict
                echo json_encode(["error" => "Username already exists"]);
                exit;
            }

            $stmt = $pdo->prepare("INSERT INTO User (Username, Password, Role) VALUES (?, ?, ?)");
            $stmt->execute([$data['Username'], $hashedPassword, $data['Role']]);
            $lastId = $pdo->lastInsertId();
            http_response_code(201); // Created
            echo json_encode(["success" => true, "UserID" => $lastId]);
        } catch (PDOException $e) {
            http_response_code(500);
            // Check for specific integrity constraint violation (like unique username)
            if ($e->getCode() == '23000') {
                 http_response_code(409);
                 echo json_encode(["error" => "Database constraint violation (e.g., username already exists)", "details" => $e->getMessage()]);
            } else {
                 echo json_encode(["error" => "Failed to add user", "details" => $e->getMessage()]);
            }
        }
        break;

    case "PUT":
        if ($userID === null) {
            http_response_code(400);
            echo json_encode(["error" => "UserID is required for update"]);
            exit;
        }
        $data = json_decode(file_get_contents("php://input"), true);

        // --- Validation ---
        if (isset($data['Role']) && !in_array($data['Role'], ['student', 'teacher', 'admin'])) {
            http_response_code(400);
            echo json_encode(["error" => "Invalid user role specified"]);
            exit;
        }
         // Username usually shouldn't be changed, prevent it here
        if (isset($data['Username'])) {
             http_response_code(400);
             echo json_encode(["error" => "Username cannot be changed"]);
             exit;
         }

        $fields = [];
        $params = [];

        if (!empty($data['Password'])) {
            $hashedPassword = password_hash($data['Password'], PASSWORD_DEFAULT);
            if ($hashedPassword === false) {
                http_response_code(500);
                echo json_encode(["error" => "Password hashing failed"]);
                exit;
            }
            $fields[] = "Password = ?";
            $params[] = $hashedPassword;
        }
        if (!empty($data['Role'])) {
            $fields[] = "Role = ?";
            $params[] = $data['Role'];
        }

        if (empty($fields)) {
            http_response_code(400);
            echo json_encode(["error" => "No fields provided for update"]);
            exit;
        }

        $params[] = $userID; // Add UserID for the WHERE clause

        $sql = "UPDATE User SET " . implode(', ', $fields) . " WHERE UserID = ?";

        try {
            $stmt = $pdo->prepare($sql);
            $success = $stmt->execute($params);
             if ($success && $stmt->rowCount() > 0) {
                echo json_encode(["success" => true, "message" => "User updated successfully"]);
            } elseif ($success && $stmt->rowCount() === 0) {
                 http_response_code(404); // Or 200 OK with message "No changes made or user not found"
                 echo json_encode(["error" => "User not found or no changes made"]);
            } else {
                 http_response_code(500);
                 echo json_encode(["error" => "Failed to update user"]);
            }
        } catch (PDOException $e) {
            http_response_code(500);
            echo json_encode(["error" => "Failed to update user", "details" => $e->getMessage()]);
        }
        break;

    case "DELETE":
        if ($userID === null) {
            http_response_code(400);
            echo json_encode(["error" => "UserID is required for deletion"]);
            exit;
        }

        // IMPORTANT: Consider consequences of deleting a user.
        // The database schema uses ON DELETE CASCADE for Student and Teacher,
        // so deleting a User will automatically delete the corresponding Student/Teacher.
        // If ON DELETE RESTRICT were used, you'd need to check references first.
        try {
            $stmt = $pdo->prepare("DELETE FROM User WHERE UserID = ?");
            $success = $stmt->execute([$userID]);

            if ($success && $stmt->rowCount() > 0) {
                echo json_encode(["success" => true, "message" => "User deleted successfully"]);
            } else {
                http_response_code(404);
                echo json_encode(["error" => "User not found or already deleted"]);
            }
        } catch (PDOException $e) {
             // Handle foreign key constraint errors if CASCADE is not used or fails
             if ($e->getCode() == '23000') {
                  http_response_code(409); // Conflict - Cannot delete because it's referenced elsewhere
                  echo json_encode(["error" => "Cannot delete user: it is referenced by other records.", "details" => $e->getMessage()]);
             } else {
                  http_response_code(500);
                  echo json_encode(["error" => "Failed to delete user", "details" => $e->getMessage()]);
             }
        }
        break;

    default:
        http_response_code(405);
        echo json_encode(["error" => "Method not allowed"]);
        break;
}
?>